package com.quan.common.utils.oss.aliyun.client;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.aliyun.oss.ClientConfiguration;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.BucketInfo;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.quan.common.utils.EncryptPropertyConfigurer;
import com.quan.common.utils.oss.common.ResponseMsg;
import com.quan.common.utils.oss.common.aliyun.FilePage;
import com.quan.common.utils.oss.common.aliyun.OSSBucket;
import com.quan.common.utils.oss.common.tools.GeneratorName;

/**
 * 阿里云 OSS 工具类
 * 
 * @author yhaoquan
 * 
 */
@Component
public class AliyunOSSClient {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	// AccessKey 访问Key
	private String accessKeyId = EncryptPropertyConfigurer.getValue("aliyun.AccessKey");

	// SecretKey 密钥
	private String secretAccessKey = EncryptPropertyConfigurer.getValue("aliyun.SecretKey");
	
	private String endpoint = EncryptPropertyConfigurer.getValue("aliyun.EndPoint");
	
	
	
	public ResponseMsg upload(String bucketName, byte[] byteArray, String originalFilename, String prefixName) {
		OSSClient client = null ;
		try {
			client = getClient() ;
			
			String key = GeneratorName.fileName(originalFilename, prefixName) ;
			client.putObject(bucketName, key, new ByteArrayInputStream(byteArray)) ;
			
			OSSBucket bucket = getBucket(bucketName);
			String url = "http://"+bucket.getName()+"."+getBucket(bucketName).getEndPoint()+"/"+key;
			ResponseMsg responseMsg = new ResponseMsg(true, 200, "成功", bucketName, key, null, null, url) ;
			logger.info("上传文件[阿里云]：{}", responseMsg.toString());
			return responseMsg ;
			
		} catch (OSSException oe) {
            logger.error("Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.");
            logger.error("Error Message: " + oe.getErrorCode());
            logger.error("Error Code:       " + oe.getErrorCode());
            logger.error("Error Code:       " + oe.getErrorCode());
            logger.error("Request ID:      " + oe.getRequestId());
            logger.error("Host ID:           " + oe.getHostId());
            
            ResponseMsg responseMsg = new ResponseMsg(false, 500, "异常", bucketName, originalFilename, null, null, null) ;
    		return responseMsg ;
        } catch (ClientException ce) {
            logger.error("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            logger.error("Error Message: " + ce.getMessage());
        } finally {
            client.shutdown();
        }
		return null;
	}
	
	/**
	 * 文件列表查询
	 * @param page
	 * @return
	 */
	public FilePage listObjects(FilePage page) {
		List<FilePage> list = new ArrayList<FilePage>() ;
		OSSClient client = null ;
		try {
			client = getClient() ;
			
			ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
			listObjectsRequest.setBucketName(page.getBucketName());
			listObjectsRequest.setPrefix(page.getPrefix());
			listObjectsRequest.setMaxKeys(page.getMaxKeys());
			
			ObjectListing listObjects = null ;
			do {
				listObjects = client.listObjects(listObjectsRequest) ;
			    List<OSSObjectSummary> sums = listObjects.getObjectSummaries();
			    for (OSSObjectSummary s : sums) {
			    	list.add(new FilePage(page.getBucketName(), s.getKey(), s.getSize(), s.getLastModified())) ;
			    }
			    
			    //记录上一次查询的标记
			    page.setMarker(page.getNextMarker());
			    
			    //下一页的标记
			    page.setNextMarker(listObjects.getNextMarker());
			} while (listObjects.isTruncated());
			
			page.setList(list);
			
		} catch (OSSException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		} finally {
			if(client != null) {
				client.shutdown();
			}
		}
		
		return page ;
	}
	
	/**
	 * 删除文件
	 * @param bucketName
	 * @param key
	 * @return
	 */
	public void delete(String bucketName, String key) {
		OSSClient client = null ;
		try {
			client = getClient() ;
			client.deleteObject(bucketName, key);
		} catch (OSSException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		} finally {
			if(client != null) {
				client.shutdown();
			}
		}
	}
	/**
	 * 批量删除文件
	 * @param bucketName
	 * @param keys
	 */
	public void deleteBatch(String bucketName, String keys) {
		if(StringUtils.isNotBlank(keys)) {
			String[] split = keys.split(",") ;
			for (String key : split) {
				this.delete(bucketName, key) ;
			}
		}
	}
	
	/**
	 * 获取Bucket信息
	 * @param bucketName
	 * @return
	 */
	public OSSBucket getBucket(String bucketName) {
		OSSClient client = null ;
		try {
			client = getClient() ;
			BucketInfo bucketInfo = client.getBucketInfo(bucketName);
			return new OSSBucket(bucketInfo.getBucket().getName(), bucketInfo.getBucket().getExtranetEndpoint(), bucketInfo.getBucket().getLocation()) ;
		} catch (OSSException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		} finally {
			if(client != null) {
				client.shutdown();
			}
		}
		return null;
	}
	
	/**
	 * 列举空间Buckets
	 * @return
	 */
	public List<OSSBucket> listBuckets() {
		List<OSSBucket> list = new ArrayList<OSSBucket>() ;
		OSSClient client = null ;
		try {
			client = getClient() ;
			List<Bucket> listBuckets = client.listBuckets() ;
			for (Bucket bucket : listBuckets) {
				list.add(new OSSBucket(bucket.getName(), bucket.getExtranetEndpoint(), bucket.getLocation())) ;
			}
		} catch (OSSException e) {
			e.printStackTrace();
		} catch (ClientException e) {
			e.printStackTrace();
		} finally {
			if(client != null) {
				client.shutdown();
			}
		}
		return list ;
	}
	
	
	/**
	 * 获取OSSClient对象
	 * @return
	 */
	public OSSClient getClient() {
		ClientConfiguration clientConfiguration = new ClientConfiguration();
		clientConfiguration.setConnectionTimeout(50000);
		clientConfiguration.setConnectionRequestTimeout(50000);
		return new OSSClient(this.endpoint, this.accessKeyId, this.secretAccessKey, clientConfiguration) ;
	}
	
	/**
	 * 获取OSSClient对象，前端指定endpoint
	 * @return
	 */
	public OSSClient getClient(String endpoint) {
		ClientConfiguration clientConfiguration = new ClientConfiguration();
		clientConfiguration.setConnectionTimeout(50000);
		clientConfiguration.setConnectionRequestTimeout(50000);
		return new OSSClient(endpoint, this.accessKeyId, this.secretAccessKey, clientConfiguration) ;
	}

}
